from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Dict, Any, Optional
import uuid
from parameter_collector import FloodForecastParameterCollector
import json
import sys
from loguru import logger

# 配置loguru日志
logger.remove()  # 移除默认配置

# 控制台日志 - 显示INFO及以上级别
logger.add(
    sys.stdout,
    level="INFO",
    format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    colorize=True
)

# 文件日志 - 详细日志，包含DEBUG级别
logger.add(
    "logs/flood_forecast_api_service.log",
    level="DEBUG",
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} | {process.id} | {thread.id} - {message}",
    rotation="10 MB",
    retention="7 days",
    compression="zip",
    encoding="utf-8"
)

# 错误日志单独文件
logger.add(
    "logs/flood_forecast_api_service_error.log",
    level="ERROR",
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} | {process.id} | {thread.id} - {message}\n{exception}",
    rotation="5 MB",
    retention="30 days",
    compression="zip",
    encoding="utf-8"
)

app = FastAPI(title="洪水预报参数收集服务", version="1.0.0")

# 存储会话状态
sessions: Dict[str, FloodForecastParameterCollector] = {}

class UserInputRequest(BaseModel):
    session_id: Optional[str] = None
    user_input: str
    
class ParameterCollectionResponse(BaseModel):
    session_id: str
    response: str
    status: str  # collecting, completed, error
    parameters: Dict[str, Any]
    missing_parameters: list
    extracted_this_turn: Dict[str, Any]
    
class SessionStatusResponse(BaseModel):
    session_id: str
    status: str
    parameters: Dict[str, Any]
    missing_parameters: list

@app.post("/flood_forecast/collect_parameters", response_model=ParameterCollectionResponse)
async def collect_parameters(request: UserInputRequest):
    """
    收集洪水预报参数
    
    Args:
        request: 包含用户输入和可选会话ID的请求
        
    Returns:
        参数收集响应，包含AI回复和当前状态
    """
    try:
        logger.info(f"收到参数收集请求: {request.user_input[:100]}...")
        
        # 获取或创建会话
        session_id = request.session_id
        if not session_id:
            # 如果没有提供session_id，生成新的
            session_id = str(uuid.uuid4())
            sessions[session_id] = FloodForecastParameterCollector()
            logger.info(f"创建新会话（无session_id）: {session_id}")
        elif session_id not in sessions:
            # 如果提供了session_id但不存在，使用提供的ID创建会话
            sessions[session_id] = FloodForecastParameterCollector()
            logger.info(f"创建新会话（使用提供的session_id）: {session_id}")
        else:
            logger.debug(f"使用现有会话: {session_id}")
            
        collector = sessions[session_id]
        
        # 处理用户输入
        logger.debug(f"处理用户输入: {request.user_input}")
        result = collector.process_user_input(request.user_input)
        
        logger.info(f"参数收集状态: {result['status']}, 缺失参数: {len(result['missing_parameters'])}")
        
        return ParameterCollectionResponse(
            session_id=session_id,
            response=result["response"],
            status=result["status"],
            parameters=result["parameters"],
            missing_parameters=result["missing_parameters"],
            extracted_this_turn=result["extracted_this_turn"]
        )
        
    except Exception as e:
        logger.error(f"处理参数收集请求时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"处理请求时发生错误: {str(e)}")

@app.get("/flood_forecast/session/{session_id}/status", response_model=SessionStatusResponse)
async def get_session_status(session_id: str):
    """
    获取会话状态
    
    Args:
        session_id: 会话ID
        
    Returns:
        会话状态信息
    """
    if session_id not in sessions:
        raise HTTPException(status_code=404, detail="会话不存在")
        
    collector = sessions[session_id]
    
    return SessionStatusResponse(
        session_id=session_id,
        status=collector.conversation_state,
        parameters={k: v["value"] for k, v in collector.required_parameters.items()},
        missing_parameters=collector._get_missing_parameters()
    )

@app.get("/flood_forecast/session/{session_id}/final_json")
async def get_final_parameters_json(session_id: str):
    """
    获取最终的参数JSON
    
    Args:
        session_id: 会话ID
        
    Returns:
        最终的参数JSON字符串
    """
    if session_id not in sessions:
        raise HTTPException(status_code=404, detail="会话不存在")
        
    collector = sessions[session_id]
    
    if collector.conversation_state != "completed":
        raise HTTPException(status_code=400, detail="参数收集尚未完成")
        
    try:
        final_json = collector.get_final_parameters_json()
        return {"final_parameters": json.loads(final_json)}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"生成最终参数时发生错误: {str(e)}")

@app.delete("/flood_forecast/session/{session_id}")
async def delete_session(session_id: str):
    """
    删除会话
    
    Args:
        session_id: 会话ID
    """
    if session_id not in sessions:
        raise HTTPException(status_code=404, detail="会话不存在")
        
    del sessions[session_id]
    return {"message": "会话已删除"}

@app.post("/flood_forecast/session/{session_id}/reset")
async def reset_session(session_id: str):
    """
    重置会话
    
    Args:
        session_id: 会话ID
    """
    if session_id not in sessions:
        raise HTTPException(status_code=404, detail="会话不存在")
        
    sessions[session_id].reset()
    return {"message": "会话已重置"}

@app.get("/flood_forecast/health")
async def health_check():
    """
    健康检查
    """
    return {
        "status": "healthy",
        "active_sessions": len(sessions),
        "service": "洪水预报参数收集服务"
    }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8001)